home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / DirectInput / DIConfig / uiglobals.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  17.9 KB  |  766 lines

  1. //-----------------------------------------------------------------------------
  2. // File: uiglobals.cpp
  3. //
  4. // Desc: CUIGlobals is a class that packs and holds most information
  5. //       relevent to a UI session.  Many classes make reference to
  6. //       CUIGlobals all the time.
  7. //
  8. //       CPaintHelper encapsulates GDI calls, simplifying GDI operations.
  9. //
  10. // Copyright (C) Microsoft Corporation. All Rights Reserved.
  11. //-----------------------------------------------------------------------------
  12.  
  13. #include "common.hpp"
  14. #define __DEFINE_ELEMENT_STRUCTURES__
  15. #include "uielements.h"
  16.  
  17.  
  18. static const GUID GUID_DIConfigAppEditLayout = 
  19. { 0xfd4ace13, 0x7044, 0x4204, { 0x8b, 0x15, 0x9, 0x52, 0x86, 0xb1, 0x2e, 0xad } };
  20.  
  21.  
  22. CUIGlobals::CUIGlobals(UIG_PARAMS_DEFINE) :
  23.  
  24.     // globals...
  25.     m_hrInit(S_OK),
  26.  
  27.     m_hrFinalResult(S_OK),
  28.  
  29.     m_hInst(NULL),
  30.     m_lpDI(NULL),
  31.  
  32.     m_dwFlags(0),
  33.     m_wszUserNames(NULL),
  34.     m_pSurface(NULL),
  35.     m_pSurface3D(NULL),
  36.     m_lpCallback(NULL),
  37.     m_pvRefData(NULL),
  38.  
  39.     m_bAllowEditLayout(FALSE),
  40.  
  41.     m_bUseColorSet(FALSE),
  42.  
  43.     // ui...
  44.     m_pElement(NULL),
  45.     m_nElements(0),
  46.     m_pFont(NULL),
  47.     m_nFonts(0),
  48.     m_pBrush(NULL),
  49.     m_nBrushes(0),
  50.     m_pPen(NULL),
  51.     m_nPens(0),
  52.     m_pColor(NULL),
  53.     m_nColors(0)
  54. {
  55.     m_hrInit = Init(UIG_PARAMS_DEFINE_PASS);
  56. }
  57.  
  58. void CUIGlobals::SetTableColor(UICOLOR uic, COLORREF c)
  59. {
  60.     UICOLORINFO *info = GetColorInfo(uic);
  61.     assert(info != NULL);
  62.     if (info == NULL)
  63.         return;
  64.  
  65.     info->rgb = c;
  66. }
  67.  
  68. HRESULT CUIGlobals::Init(UIG_PARAMS_DEFINE)
  69. {
  70.     HRESULT hr = S_OK;
  71.  
  72.     // get instance handle
  73.     m_hInst = (HINSTANCE)g_hModule;
  74.     if (m_hInst == NULL)
  75.     {
  76.         etrace(_T("hInst NULL\n"));
  77.         return E_FAIL;
  78.     }
  79.  
  80.     // create direct input
  81.     DWORD dwVer = DIRECTINPUT_VERSION;
  82.     hr = DirectInput8Create(m_hInst, dwVer, IID_IDirectInput8W, (LPVOID *)&m_lpDI, NULL);
  83.     if (FAILED(hr) || m_lpDI == NULL)
  84.     {
  85.         m_lpDI = NULL;
  86.         etrace2(_T("Could not create DirectInput ver 0x%08x\n  -> DirectInputCreateEx() returned 0x%08x\n"), dwVer, hr);
  87.         return hr;
  88.     }
  89.  
  90.     // save flags
  91.     m_dwFlags = dwFlags;
  92. #ifdef CFGUI__FORCE_NON_NULL_WSZUSERNAMES
  93.     if (wszUserNames == NULL)
  94.         wszUserNames = _T("Forced Non-NULL Username");
  95. #endif
  96.     if (wszUserNames == NULL)
  97.     {
  98.         etrace(_T("wszUserNames was passed NULL\n"));
  99.         return E_FAIL;
  100.     }
  101.  
  102.     // save user names
  103.     m_wszUserNames = DupSuperString(wszUserNames);
  104.     if (m_wszUserNames == NULL)
  105.     {
  106.         etrace(_T("Could not duplicate user names\n"));
  107.         return E_FAIL;
  108.     }
  109.  
  110.     // make sure we were passed an action format
  111.     if (lpAcFor == NULL)
  112.     {
  113.         etrace(_T("lpAcFor param NULL\n"));
  114.         return E_INVALIDARG;
  115.     }
  116.  
  117.     // copy the acfor to the master
  118.     hr = InitMasterAcForArray(lpAcFor, int(dwNumAcFor));
  119.     if (FAILED(hr))
  120.     {
  121.         etrace1(_T("InitMasterAcForArray() failed, returning 0x%08x\n"), hr);
  122.         return hr;
  123.     }
  124.  
  125.     // get surface
  126.     if (lpSurface != NULL)
  127.     {
  128.         hr = lpSurface->QueryInterface(IID_IDirect3DSurface9, (void **)&m_pSurface3D);
  129.         if (FAILED(hr) || m_pSurface3D == NULL)
  130.         {
  131.             m_pSurface3D = NULL;
  132.         }
  133.  
  134.         hr = lpSurface->QueryInterface(IID_IDirectDrawSurface, (void **)&m_pSurface);
  135.         if (FAILED(hr) || m_pSurface == NULL)
  136.         {
  137.             m_pSurface = NULL;
  138.         }
  139.  
  140.         if (m_pSurface == NULL && m_pSurface3D == NULL)
  141.             etrace(_T("lpSurface was non-NULL but could not get IDirect3DSurface9 or IID_IDirectDrawSurface from it"));
  142.     }
  143.  
  144.     // save callback and ref data
  145.     m_lpCallback = lpCallback;
  146.     m_pvRefData = pvRefData;
  147.  
  148.     // see whether or not we're allowing edit layout mode
  149.     m_bAllowEditLayout = IsEqualGUID(RefMasterAcFor(0).guidActionMap,
  150.         GUID_DIConfigAppEditLayout);
  151.  
  152.     // init a bunch of stuff necessary for painting
  153.     if (!InitColorsAndTablesAndObjects(lpDIColorSet))
  154.         return E_FAIL;
  155.  
  156.     // dump info if debug
  157. #ifdef DBG
  158.     Dump();
  159. #endif
  160.  
  161.     // return success if we got here
  162.     return S_OK;
  163. }
  164.  
  165. BOOL CUIGlobals::InitColorsAndTablesAndObjects(LPDICOLORSET lpDIColorSet)
  166. {
  167.     // init ui tables
  168.     if (!InitTables())
  169.     {
  170.         etrace(_T("Could not initialize tables\n"));
  171.         return FALSE;
  172.     }
  173.  
  174.     // decide whether or not to use the passed colorset
  175.     if (lpDIColorSet != NULL)
  176.     {
  177.         m_ColorSet = *lpDIColorSet;
  178.  
  179.         m_bUseColorSet = !IsZeroOrInvalidColorSet(m_ColorSet);
  180.     }
  181.     else
  182.         m_bUseColorSet = FALSE;
  183.  
  184.     // use it, or use defaults
  185.     if (m_bUseColorSet)
  186.     {
  187.         // transfer colors from passed colorset
  188.         SetTableColor(UIC_TEXTFORE, D3DCOLOR2COLORREF(m_ColorSet.cTextFore));
  189.         SetTableColor(UIC_TEXTHIGHLIGHT, D3DCOLOR2COLORREF(m_ColorSet.cTextHighlight));
  190.         SetTableColor(UIC_CALLOUTLINE, D3DCOLOR2COLORREF(m_ColorSet.cCalloutLine));
  191.         SetTableColor(UIC_CALLOUTHIGHLIGHT, D3DCOLOR2COLORREF(m_ColorSet.cCalloutHighlight));
  192.         SetTableColor(UIC_BORDER, D3DCOLOR2COLORREF(m_ColorSet.cBorder));
  193.         SetTableColor(UIC_CONTROLFILL, D3DCOLOR2COLORREF(m_ColorSet.cControlFill));
  194.         SetTableColor(UIC_HIGHLIGHTFILL, D3DCOLOR2COLORREF(m_ColorSet.cHighlightFill));
  195.         SetTableColor(UIC_AREAFILL, D3DCOLOR2COLORREF(m_ColorSet.cAreaFill));
  196.     }
  197.     else
  198.     {
  199.         // use default colors
  200.         SetTableColor(UIC_TEXTFORE,                RGB(255, 255, 255));
  201.         SetTableColor(UIC_TEXTHIGHLIGHT,        RGB(  0, 255,   0));
  202.         SetTableColor(UIC_CALLOUTLINE,            RGB(255, 255, 255));
  203.         SetTableColor(UIC_CALLOUTHIGHLIGHT,        RGB(  0, 255,   0));
  204.         SetTableColor(UIC_BORDER,                RGB(255, 255,   0));
  205.         SetTableColor(UIC_CONTROLFILL,            RGB(  0, 191,   0));
  206.         SetTableColor(UIC_HIGHLIGHTFILL,        RGB(  0,   0,   0));
  207.         SetTableColor(UIC_AREAFILL,                RGB(  0,   0,   0));
  208.     }
  209.  
  210.     // create the table objects
  211.     CreateObjects();
  212.  
  213.     return TRUE;
  214. }
  215.  
  216. CUIGlobals::~CUIGlobals()
  217. {
  218.     if (m_wszUserNames != NULL)
  219.         free((LPVOID)m_wszUserNames);
  220.     m_wszUserNames = NULL;
  221.  
  222.     if (m_lpDI != NULL)
  223.         m_lpDI->Release();
  224.     m_lpDI = NULL;
  225.  
  226.     if (m_pSurface != NULL)
  227.         m_pSurface->Release();
  228.     m_pSurface = NULL;
  229.  
  230.     if (m_pSurface3D != NULL)
  231.         m_pSurface3D->Release();
  232.     m_pSurface3D = NULL;
  233.  
  234.     ClearMasterAcForArray();
  235.  
  236.     ClearTables();
  237. }
  238.  
  239. void CUIGlobals::Dump()
  240. {
  241.     tracescope(ts, _T("UIGlobals...\n\n"));
  242.  
  243.     traceHEXPTR(m_hInst);
  244.     traceHEXPTR(m_lpDI);
  245.     LPTSTR str = AllocConfigureFlagStr(m_dwFlags);
  246.     trace1(_T("m_dwFlags = %s\n"), str);
  247.     free(str);
  248.     traceSUPERSTR(m_wszUserNames);
  249.     traceHEXPTR(m_pSurface);
  250.     traceHEXPTR(m_pSurface3D);
  251.     traceHEXPTR(m_lpCallback);
  252.     traceBOOL(m_bAllowEditLayout);
  253.     {
  254.         tracescope(__csts, _T("m_ColorSet...\n"));
  255.         traceHEX(m_ColorSet.cTextFore);
  256.         traceHEX(m_ColorSet.cTextHighlight);
  257.         traceHEX(m_ColorSet.cCalloutLine);
  258.         traceHEX(m_ColorSet.cCalloutHighlight);
  259.         traceHEX(m_ColorSet.cBorder);
  260.         traceHEX(m_ColorSet.cControlFill);
  261.         traceHEX(m_ColorSet.cHighlightFill);
  262.         traceHEX(m_ColorSet.cAreaFill);
  263.     }
  264.     traceBOOL(m_bUseColorSet);
  265.     trace(_T("\n"));
  266.     TraceActionFormat(_T("Master ActionFormat 0:"), RefMasterAcFor(0));
  267.     trace(_T("\n\n"));
  268. }
  269.  
  270. LPDIRECTINPUT8W CUIGlobals::GetDI()
  271. {
  272.     if (m_lpDI == NULL)
  273.         return NULL;
  274.  
  275.     m_lpDI->AddRef();
  276.     return m_lpDI;
  277. }
  278.  
  279. IDirectDrawSurface *CUIGlobals::GetSurface()
  280. {
  281.     if (m_pSurface == NULL)
  282.         return NULL;
  283.  
  284.     m_pSurface->AddRef();
  285.     return m_pSurface;
  286. }
  287.  
  288. IDirect3DSurface9 *CUIGlobals::GetSurface3D()
  289. {
  290.     if (m_pSurface3D == NULL)
  291.         return NULL;
  292.  
  293.     m_pSurface3D->AddRef();
  294.     return m_pSurface3D;
  295. }
  296.  
  297. void CUIGlobals::DeleteObjects()
  298. {
  299.     // make sure all our gdi objects are deleted
  300.     int i;
  301.     if (m_pFont != NULL)
  302.         for (i = 0; i <    m_nFonts; i++)
  303.         {
  304.             UIFONTINFO &info = m_pFont[i];
  305.             if (info.hFont != NULL)
  306.                 DeleteObject(info.hFont);
  307.             info.hFont = NULL;
  308.         }
  309.     if (m_pBrush != NULL)
  310.         for (i = 0; i <    m_nBrushes; i++)
  311.         {
  312.             UIBRUSHINFO &info = m_pBrush[i];
  313.             if (info.hBrush != NULL)
  314.                 DeleteObject(info.hBrush);
  315.             info.hBrush = NULL;
  316.             if (info.hPen != NULL)
  317.                 DeleteObject(info.hPen);
  318.             info.hPen = NULL;
  319.         }
  320.     if (m_pPen != NULL)
  321.         for (i = 0; i <    m_nPens; i++)
  322.         {
  323.             UIPENINFO &info = m_pPen[i];
  324.             if (info.hPen != NULL)
  325.                 DeleteObject(info.hPen);
  326.             info.hPen = NULL;
  327.         }
  328. }
  329.  
  330. void CUIGlobals::ClearTables()
  331. {
  332.     // make sure all our gdi objects are deleted
  333.     DeleteObjects();
  334.  
  335.     // delete the tables, null the pointers, and zero the counters
  336. #define FREETABLE(member, memnum) \
  337. { \
  338.     if (member != NULL) \
  339.         delete [] member; \
  340.     member = NULL; \
  341.     memnum = 0; \
  342. }
  343.     FREETABLE(m_pElement, m_nElements);
  344.     FREETABLE(m_pFont, m_nFonts);
  345.     FREETABLE(m_pBrush, m_nBrushes);
  346.     FREETABLE(m_pPen, m_nPens);
  347.     FREETABLE(m_pColor, m_nColors);
  348. }
  349.  
  350. BOOL CUIGlobals::InitTables()
  351. {
  352.     BOOL bSuccess = TRUE;
  353.  
  354.     // make sure the tables have been cleared
  355.     ClearTables();
  356.  
  357.     // allocate our own copies of all the tables
  358. #define ALLOCTABLE(member, memnum, type, init, num) \
  359. { \
  360.     member = new type [memnum = num]; \
  361.     if (member == NULL) \
  362.     { \
  363.         memnum = 0; \
  364.         bSuccess = FALSE; \
  365.     } \
  366.     else \
  367.         memcpy(member, init, sizeof(type) * memnum); \
  368. }
  369.     ALLOCTABLE(m_pElement, m_nElements, UIELEMENTINFO, uielement, NUMUIELEMENTS);
  370.     ALLOCTABLE(m_pFont, m_nFonts, UIFONTINFO, uifont, NUMUIFONTS);
  371.     ALLOCTABLE(m_pBrush, m_nBrushes, UIBRUSHINFO, uibrush, NUMUIBRUSHES);
  372.     ALLOCTABLE(m_pPen, m_nPens, UIPENINFO, uipen, NUMUIPENS);
  373.     ALLOCTABLE(m_pColor, m_nColors, UICOLORINFO, uicolor, NUMUICOLORS);
  374.  
  375.     return bSuccess;
  376. }
  377.  
  378. void CUIGlobals::RecreateObjects()
  379. {
  380.     DeleteObjects();
  381.     CreateObjects();
  382. }
  383.  
  384. void CUIGlobals::CreateObjects()
  385. {
  386.     // make sure all our gdi objects are created
  387.     int i;
  388.     if (m_pFont != NULL)
  389.     {
  390.         HDC hDC = GetDC(NULL);
  391.         for (i = 0; i <    m_nFonts; i++)
  392.         {
  393.             UIFONTINFO &info = m_pFont[i];
  394.             if (info.hFont == NULL)
  395.             {
  396.                 LOGFONT lf;
  397.                 lf.lfHeight = -MulDiv(info.nPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  398.                 lf.lfWidth = 0;
  399.                 lf.lfEscapement = 0;
  400.                 lf.lfOrientation = 0;
  401.                 lf.lfWeight = info.bBold ? FW_BOLD : FW_NORMAL;
  402.                 lf.lfItalic = FALSE;
  403.                 lf.lfUnderline = FALSE;
  404.                 lf.lfStrikeOut = FALSE;
  405.                 lf.lfCharSet = DEFAULT_CHARSET;
  406.                 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
  407.                 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  408.                 lf.lfQuality = PROOF_QUALITY;
  409.                 lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  410.                 _tcscpy(lf.lfFaceName, info.lfFaceName);
  411.  
  412.                 info.hFont = (HGDIOBJ)CreateFontIndirect(&lf);
  413.             }
  414.         }
  415.         ReleaseDC(NULL, hDC);
  416.     }
  417.     if (m_pBrush != NULL)
  418.         for (i = 0; i <    m_nBrushes; i++)
  419.         {
  420.             UIBRUSHINFO &info = m_pBrush[i];
  421.             if (info.hBrush == NULL)
  422.                 info.hBrush = (HGDIOBJ)CreateSolidBrush(GetColor(info.eColor));
  423.             if (info.hPen == NULL)
  424.                 info.hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, GetColor(info.eColor));
  425.         }
  426.     if (m_pPen != NULL)
  427.         for (i = 0; i <    m_nPens; i++)
  428.         {
  429.             UIPENINFO &info = m_pPen[i];
  430.             if (info.hPen == NULL)
  431.                 info.hPen = (HGDIOBJ)CreatePen(info.fnPenStyle, info.nWidth, GetColor(info.eColor));
  432.         }
  433. }
  434.  
  435.  
  436. #define IMPLGETINFO(Type, TYPE, Types, t) \
  437. UI##TYPE##INFO *CUIGlobals::Get##Type##Info(UI##TYPE t) \
  438. { \
  439.     if (m_p##Type != NULL) \
  440.         for (int i = 0; i < m_n##Types; i++) \
  441.             if (m_p##Type[i].e##Type == t) \
  442.                 return &(m_p##Type[i]); \
  443.     return NULL; \
  444. }
  445.  
  446. IMPLGETINFO(Element, ELEMENT, Elements, e)
  447. IMPLGETINFO(Font, FONT, Fonts, f)
  448. IMPLGETINFO(Brush, BRUSH, Brushes, b)
  449. IMPLGETINFO(Pen, PEN, Pens, p)
  450. IMPLGETINFO(Color, COLOR, Colors, c)
  451.  
  452. #undef IMPLGETINFO
  453.  
  454.  
  455. #define IMPLGET(T, Name, Type, TYPE, v, def, ret) \
  456. T CUIGlobals::Get##Name(UI##TYPE ui##v) \
  457. { \
  458.     UI##TYPE##INFO *v = Get##Type##Info(ui##v); \
  459.     if (!v) \
  460.         return def; \
  461.     return ret; \
  462. }
  463.  
  464. IMPLGET(HGDIOBJ, Font, Element, ELEMENT, e, NULL, GetFont(e->eFont))
  465. IMPLGET(HGDIOBJ, Font, Font, FONT, f, NULL, f->hFont)
  466. IMPLGET(HGDIOBJ, Brush, Element, ELEMENT, e, NULL, GetBrush(e->eBrush))
  467. IMPLGET(HGDIOBJ, Brush, Brush, BRUSH, b, NULL, b->hBrush)
  468. IMPLGET(HGDIOBJ, Pen, Element, ELEMENT, e, NULL, GetPen(e->ePen))
  469. IMPLGET(HGDIOBJ, Pen, Brush, BRUSH, b, NULL, b->hPen)
  470. IMPLGET(HGDIOBJ, Pen, Pen, PEN, p, NULL, p->hPen)
  471. IMPLGET(COLORREF, BrushColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eBrush))
  472. IMPLGET(COLORREF, PenColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->ePen))
  473. IMPLGET(COLORREF, TextColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eText))
  474. IMPLGET(COLORREF, BkColor, Element, ELEMENT, e, RGB(255, 127, 127), GetColor(e->eBk))
  475. IMPLGET(COLORREF, Color, Brush, BRUSH, b, RGB(255, 127, 127), GetColor(b->eColor))
  476. IMPLGET(COLORREF, Color, Pen, PEN, p, RGB(255, 127, 127), GetColor(p->eColor))
  477. IMPLGET(COLORREF, Color, Color, COLOR, c, RGB(255, 127, 127), c->rgb)
  478.  
  479. #undef IMPLGET
  480.  
  481.  
  482. CPaintHelper::CPaintHelper(CUIGlobals &uig, HDC hDC) :
  483.     m_uig(uig), m_priv_hDC(hDC), m_hDC(m_priv_hDC),
  484.     m_eFont(UIF_VOID),
  485.     m_eBrush(UIB_VOID),
  486.     m_ePen(UIP_VOID),
  487.     m_eText(UIC_VOID),
  488.     m_eBk(UIC_VOID),
  489.     m_hOldFont(NULL), m_hOldBrush(NULL), m_hOldPen(NULL),
  490.     m_bOldFont(FALSE), m_bOldBrush(FALSE), m_bOldPen(FALSE)
  491. {
  492.     if (m_hDC != NULL)
  493.     {
  494.         m_oldtextcolor = GetTextColor(m_hDC);
  495.         m_oldbkcolor = GetBkColor(m_hDC);
  496.         m_oldbkmode = GetBkMode(m_hDC);
  497.     }
  498. }
  499.  
  500. CPaintHelper::~CPaintHelper()
  501. {
  502.     if (m_hDC != NULL)
  503.     {
  504.         if (m_bOldFont)
  505.             SelectObject(m_hDC, m_hOldFont);
  506.         if (m_bOldBrush)
  507.             SelectObject(m_hDC, m_hOldBrush);
  508.         if (m_bOldPen)
  509.             SelectObject(m_hDC, m_hOldPen);
  510.  
  511.         SetTextColor(m_hDC, m_oldtextcolor);
  512.         SetBkColor(m_hDC, m_oldbkcolor);
  513.         SetBkMode(m_hDC, m_oldbkmode);
  514.     }
  515. }
  516.  
  517. void CPaintHelper::SetElement(UIELEMENT eElement)
  518. {
  519.     UIELEMENTINFO *info = m_uig.GetElementInfo(eElement);
  520.     if (!info)
  521.         return;
  522.  
  523.     if (info->eFont != UIF_LAST)
  524.         SetFont(info->eFont);
  525.     if (info->eBrush != UIB_LAST)
  526.         SetBrush(info->eBrush);
  527.     if (info->ePen != UIP_LAST)
  528.         SetPen(info->ePen);
  529.     SetText(info->eText, info->eBk);
  530. }
  531.  
  532. void CPaintHelper::SetFont(UIFONT eFont)
  533. {
  534.     if (m_eFont == eFont || eFont == UIF_LAST)
  535.         return;
  536.  
  537.     HGDIOBJ hObj = m_uig.GetFont(eFont);
  538.     if (hObj == NULL)
  539.         return;
  540.  
  541.     if (m_hDC != NULL)
  542.     {
  543.         HGDIOBJ hOld = NULL;
  544.         hOld = SelectObject(m_hDC, hObj);
  545.         if (!m_bOldFont)
  546.             m_hOldFont = hOld;
  547.         m_bOldFont = TRUE;
  548.     }
  549.  
  550.     m_eFont = eFont;
  551. }
  552.  
  553. void CPaintHelper::SetBrush(UIBRUSH eBrush)
  554. {
  555.     if (m_eBrush == eBrush || eBrush == UIB_LAST)
  556.         return;
  557.  
  558.     HGDIOBJ hObj = eBrush == UIB_NULL ?
  559.         GetStockObject(NULL_BRUSH) :
  560.         m_uig.GetBrush(eBrush);
  561.     if (hObj == NULL)
  562.         return;
  563.  
  564.     if (m_hDC != NULL)
  565.     {
  566.         HGDIOBJ hOld = NULL;
  567.         hOld = SelectObject(m_hDC, hObj);
  568.         if (!m_bOldBrush)
  569.             m_hOldBrush = hOld;
  570.         m_bOldBrush = TRUE;
  571.     }
  572.  
  573.     m_eBrush = eBrush;
  574. }
  575.  
  576. void CPaintHelper::SetPen(UIPEN ePen)
  577. {
  578.     if (m_ePen == ePen || ePen == UIP_LAST)
  579.         return;
  580.  
  581.     HGDIOBJ hObj = ePen == UIB_NULL ?
  582.         GetStockObject(NULL_PEN) :
  583.         m_uig.GetPen(ePen);
  584.     if (hObj == NULL)
  585.         return;
  586.  
  587.     if (m_hDC != NULL)
  588.     {
  589.         HGDIOBJ hOld = NULL;
  590.         hOld = SelectObject(m_hDC, hObj);
  591.         if (!m_bOldPen)
  592.             m_hOldPen = hOld;
  593.         m_bOldPen = TRUE;
  594.     }
  595.  
  596.     m_ePen = ePen;
  597. }
  598.  
  599. void CPaintHelper::SetText(UICOLOR eText, UICOLOR eBk)
  600. {
  601.     if (m_eText != eText && eText != UIC_LAST)
  602.     {
  603.         if (m_hDC != NULL)
  604.             SetTextColor(m_hDC, m_uig.GetColor(eText));
  605.         m_eText = eText;
  606.     }
  607.     if (m_eBk != eBk && eBk != UIC_LAST)
  608.     {
  609.         if (m_hDC != NULL)
  610.         {
  611.             if (eBk == UIC_NULL)
  612.                 SetBkMode(m_hDC, TRANSPARENT);
  613.             else 
  614.             {
  615.                 SetBkColor(m_hDC, m_uig.GetColor(eBk));
  616.                 SetBkMode(m_hDC, OPAQUE);
  617.             }
  618.         }
  619.         m_eBk = eBk;
  620.     }
  621. }
  622.  
  623. BOOL CPaintHelper::LineTo(int x, int y)
  624. {
  625.     if (m_hDC == NULL)
  626.         return FALSE;
  627.  
  628.     return ::LineTo(m_hDC, x, y);
  629. }
  630.  
  631. BOOL CPaintHelper::MoveTo(int x, int y, SPOINT *last)
  632. {
  633.     if (m_hDC == NULL)
  634.         return FALSE;
  635.  
  636.     POINT p;
  637.     BOOL bRet = MoveToEx(m_hDC, x, y, &p);
  638.     if (last)
  639.         *last = p;
  640.     return bRet;
  641. }
  642.  
  643. BOOL CPaintHelper::Rectangle(SRECT r, UIRECTTYPE eType)
  644. {
  645.     // fail on no dc
  646.     if (m_hDC == NULL)
  647.         return FALSE;
  648.  
  649.     // see if we lack a pen or brush (might add more checks later)
  650.     BOOL bNoPen = m_ePen == UIP_NULL;
  651.     BOOL bNoBrush = m_eBrush == UIB_NULL;
  652.  
  653.     // fail if trying to do an outline without a pen
  654.     if (eType == UIR_OUTLINE && bNoPen)
  655.         return FALSE;
  656.  
  657.     // fail if trying to do a solid without a brush
  658.     if (eType == UIR_SOLID && bNoBrush)
  659.         return FALSE;
  660.  
  661.     // save old objects if we change anything...
  662.     HGDIOBJ hOldBrush = NULL, hOldPen = NULL;
  663.  
  664.     // select a null brush if we're doing an outline and we're not already null brushed
  665.     if (eType == UIR_OUTLINE && m_eBrush != UIB_NULL)
  666.         hOldBrush = SelectObject(m_hDC, GetStockObject(NULL_BRUSH));
  667.  
  668.     // select a pen the same color as the current brush if doing solid
  669.     if (eType == UIR_SOLID || m_ePen == UIP_NULL)
  670.     {
  671.         HGDIOBJ hPen = m_uig.GetPen(m_eBrush);
  672.         if (hPen == NULL)
  673.             return FALSE;
  674.         hOldPen = SelectObject(m_hDC, hPen);
  675.     }
  676.  
  677.     // draw the rect
  678.     BOOL bRet = ::Rectangle(m_hDC, r.left, r.top, r.right, r.bottom);
  679.  
  680.     // restore whatever changed
  681.     if (eType == UIR_OUTLINE && m_eBrush != UIB_NULL)
  682.         SelectObject(m_hDC, hOldBrush);
  683.     if (eType == UIR_SOLID || m_ePen == UIP_NULL)
  684.         SelectObject(m_hDC, hOldPen);
  685.  
  686.     return bRet;
  687. }
  688.  
  689. const DIACTIONFORMATW &CUIGlobals::RefMasterAcFor(int i)
  690. {
  691.     assert(IsValidMasterAcForIndex(i));
  692.     return m_MasterAcForArray[i];
  693. }
  694.  
  695. BOOL CUIGlobals::IsValidMasterAcForIndex(int i)
  696. {
  697.     if (i < 0 || i >= m_MasterAcForArray.GetSize())
  698.         return FALSE;
  699.  
  700.     return TRUE;
  701. }
  702.  
  703. HRESULT CUIGlobals::InitMasterAcForArray(const DIACTIONFORMATW *af, int n)
  704. {
  705.     if (n < 1)
  706.         return E_FAIL;
  707.  
  708.     ClearMasterAcForArray();
  709.  
  710.     m_MasterAcForArray.SetSize(n);
  711.  
  712.     for (int i = 0; i < n; i++)
  713.     {
  714.         HRESULT hr = CopyActionFormat(m_MasterAcForArray[i], af[i]);
  715.         if (FAILED(hr))
  716.         {
  717.             m_MasterAcForArray.SetSize(i);
  718.             ClearMasterAcForArray();
  719.  
  720.             return hr;
  721.         }
  722.     }
  723.  
  724.     return S_OK;
  725. }
  726.  
  727. void CUIGlobals::ClearMasterAcForArray()
  728. {
  729.     int s = m_MasterAcForArray.GetSize();
  730.  
  731.     for (int i = 0; i < s; i++)
  732.         CleanupActionFormatCopy(m_MasterAcForArray[i]);
  733.  
  734.     m_MasterAcForArray.RemoveAll();
  735.     assert(m_MasterAcForArray.GetSize() == 0);
  736. }
  737.  
  738. LPCWSTR CUIGlobals::GetUserName(int i)
  739. {
  740.     return GetSubString(m_wszUserNames, i);
  741. }
  742.  
  743. int CUIGlobals::GetNumUserNames()
  744. {
  745.     return CountSubStrings(m_wszUserNames);
  746. }
  747.  
  748. void CUIGlobals::SetFinalResult(HRESULT hr)
  749. {
  750.     m_hrFinalResult = hr;
  751. }
  752.  
  753. HRESULT CUIGlobals::GetFinalResult()
  754. {
  755.     return m_hrFinalResult;
  756. }
  757.  
  758. int CUIGlobals::GetUserNameIndex(LPCWSTR wsz)
  759. {
  760.     for (int i = 0; i < GetNumUserNames(); i++)
  761.         if (_wcsicmp(wsz, GetUserName(i)) == 0)
  762.             return i;
  763.  
  764.     return -1;
  765. }
  766.